﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ATEC.GeometryNET;
using SSDPNET.Geom;
using ATEC.ATDataCoreNET;
using ATEC.ATDataCoreNET.ATObjects;
using DynamicButtons;

namespace GeometryExample
{
    /// <summary>
    /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/求交。
    /// 内容：玄镜BIM图形平台上，各种类型曲线求交例子.
    /// </summary>
    public class IntersectCurveSetMethods
    {
        //获取当前激活Scene
        public static ATSceneRef scene = SSDPNET.ScenesFunctions.SceneRefGetActive();

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/求交。
        /// 功能：弹出7个按钮，分别演示：
        ///     线段与线段求交
        ///     圆弧与圆弧求交
        ///     线段与圆弧求交
        ///     线段与平面求交
        ///     线段与B样条求交
        ///     两个B样条曲线求交
        ///     计算B样条曲线和平面的交点
        /// </summary>
        public static void IntersectGeometryExample()
        {
            //清空视口
            UseSomeBasicMethods.ClearScene();

            ButtonsView v = new ButtonsView();

            v.AddButton("线段与线段求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                Intersect2XSeg();
            });

            v.AddButton("圆弧与圆弧求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //两个Arc求交，认为圆弧有界
                Intersect2Arc();
            });

            v.AddButton("线段与圆弧求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //XSegment和XEllipse求交，椭圆弧和线段都视为无界的
                IntersectArcSeg();
            });

            v.AddButton("线段与平面求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //线段与平面求交
                IntersectSegPlane();
            });

            v.AddButton("线段与B样条曲线求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //Bspline和Xseg求交
                IntersectBsplineXseg();
            });

            v.AddButton("两个B样条曲线求交", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //两个CurveSet求交
                Intersect2BsplineObject();
            });

            v.AddButton("计算B样条曲线和平面的交点", (object sender, RoutedEventArgs e) =>
            {
                //清空视口
                UseSomeBasicMethods.ClearScene();
                //Bspline和Plane求交
                IntersectBsplinePlane();
            });

            v.Show();

        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/线段交点。
        /// 功能：计算并显示两条线段在XY平面的交点
        /// 关键类及说明：
        ///     XSegment3d: 表示3D空间中的线段
        ///     XPoint3d: 表示3D空间中的点
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateHorizonXseg: 创建水平线段
        ///     CreateCurveSetMethods.CreateXSegmentFromStartEnd: 从起点和终点创建线段
        ///     XSegment3d.IntersectXY: 计算两条线段在XY平面的交点
        ///     UseSomeBasicMethods.AddToScene_XSegment: 将线段添加到场景中
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中
        /// </summary>
        public static void Intersect2XSeg()
        {
            // 创建两条线段，并显示到界面上
            XSegment3d seg1 = CreateCurveSetMethods.CreateHorizonXseg();  // 创建一条水平线段
            XSegment3d seg2 = CreateCurveSetMethods.CreateXSegmentFromStartEnd();  // 从起点和终点创建另一条线段

            UseSomeBasicMethods.AddToScene_XSegment(seg1);  // 将第一条线段添加到场景中
            UseSomeBasicMethods.AddToScene_XSegment(seg2);  // 将第二条线段添加到场景中

            // 定义输出参数：交点以及在两个线段上的比例分数
            double fracA, fracB;  // 在两条线段上的比例分数
            XPoint3d ptA, ptB;  // 交点

            // 计算两条线段在XY平面的交点
            bool isSuccess = XSegment3d.IntersectXY(seg1, seg2, out fracA, out ptA, out fracB, out ptB);  // 计算交点，并输出比例分数和交点坐标

            UseSomeBasicMethods.AddToScene_Xpoint(ptA, 1);  // 将第一个交点添加到场景中，标记为1
            UseSomeBasicMethods.AddToScene_Xpoint(ptB, 2);  // 将第二个交点添加到场景中，标记为2
        }


        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/线段交点。
        /// 功能：计算两条线段在XY平面的交点，线段视为无限长
        /// 关键类及说明：
        ///     XSegment3d: 表示3D空间中的线段
        ///     XPoint3d: 表示3D空间中的点
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateHorizonXseg: 创建水平线段
        ///     CreateCurveSetMethods.CreateXSegmentFromStartEnd: 从起点和终点创建线段
        ///     XTransform3d.FromTranslation: 创建平移变换矩阵
        ///     XTransform3d.Multiply: 应用变换矩阵到几何对象
        ///     SSDPNET.ATVecFuncs.VecIntersect: 计算两条无限长线段的交点
        /// </summary>
        public static void Intersect2XSeg_AsVector()
        {
            // 创建两条线段，并显示到界面上
            XSegment3d seg1 = CreateCurveSetMethods.CreateHorizonXseg(); // 创建一条水平线段
            XSegment3d seg2 = CreateCurveSetMethods.CreateXSegmentFromStartEnd(); // 从起点和终点创建另一条线段

            // 把seg2向X正方向移动100单位的距离
            XSegment3d outSeg = seg2; // 复制seg2
            XTransform3d tranMoveTo = XTransform3d.FromTranslation(XVector3d.FromXYZ(100, 0, 0)); // 创建平移变换矩阵
            tranMoveTo.Multiply(out outSeg, seg2); // 应用变换矩阵到seg2

            // 计算直线的交点，认为直线无限长
            XPoint3d pt; // 存储交点
            int isSuccess = SSDPNET.ATVecFuncs.VecIntersect(out pt, seg1, outSeg); // 计算交点
        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/线段和平面的交点。
        /// 功能：计算并显示线段和平面的交点
        /// 关键类及说明：
        ///     XSegment3d: 表示3D空间中的线段
        ///     XPoint3d: 表示3D空间中的点
        ///     XPlane3d: 表示3D空间中的平面
        ///     XSegment3d.Intersect: 计算线段与平面的交点
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateHorizonXseg: 创建水平线段
        ///     UseSomeBasicMethods.AddToScene_XSegment: 将线段添加到场景中
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中
        /// </summary>
        public static void IntersectSegPlane()
        {
            // 1. 构造XSegment
            XSegment3d seg1 = CreateCurveSetMethods.CreateHorizonXseg();  // 创建一条水平线段
            UseSomeBasicMethods.AddToScene_XSegment(seg1, 4);  // 将线段添加到场景中，颜色标记为4

            // 2. 构造Plane
            XPoint3d origin = new XPoint3d(-70, -15, 0);  // 平面的原点
            XVector3d normal = XVector3d.UnitX;  // 平面的法向量
            XPlane3d plane = new XPlane3d(origin, normal);  // 创建一个平面
            {
                // 绘制平面
                CurveSet curve = CreatePlaneYOZ(origin);  // 创建一个示意平面
                UseSomeBasicMethods.AddToScene_CurveSet(curve, 3);  // 将平面添加到场景中，颜色标记为3
            }

            {
                // 出参：交点和参数
                XPoint3d ptInt;  // 交点
                double paramInt;  // 参数

                // 求交，返回是否成功
                bool isSuccess = seg1.Intersect(out ptInt, out paramInt, plane);  // 计算交点
                UseSomeBasicMethods.AddToScene_Xpoint(ptInt, 4);  // 将交点添加到场景中，颜色标记为4
            }
        }


        #region 圆弧求交
        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/圆弧和平面的交点。
        /// 功能：计算并显示圆弧和平面的交点
        /// 关键类及说明：
        ///     XEllipse3d: 表示3D空间中的椭圆
        ///     XPoint3d: 表示3D空间中的点
        ///     XPlane3d: 表示3D空间中的平面
        ///     XEllipse3d.Intersect: 计算椭圆与平面的交点
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateXEllipse3d_FromCenterRadiusNormal: 从中心、半径和法向量创建椭圆
        ///     UseSomeBasicMethods.AddToScene_XEllipse3d: 将椭圆添加到场景中
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中
        /// </summary>
        public static void IntersectArcPlane()
        {
            // 1. 构造圆弧
            XEllipse3d arc = CreateCurveSetMethods.CreateXEllipse3d_FromCenterRadiusNormal();  // 创建一个椭圆
            UseSomeBasicMethods.AddToScene_XEllipse3d(arc);  // 将椭圆添加到场景中

            // 2. 构造平面---平面是无限大的
            XPoint3d origin = new XPoint3d(-10, 50, 0);  // 平面的原点
            XVector3d normal = XVector3d.UnitX;  // 平面的法向量
            XPlane3d plane = new XPlane3d(origin, normal);  // 创建一个平面
            {
                // 绘制平面---只是一个示意
                CurveSet curve = CreatePlaneYOZ(origin);  // 创建一个示意平面
                UseSomeBasicMethods.AddToScene_CurveSet(curve, 3);  // 将平面添加到场景中，颜色标记为3
            }

            // 计算圆弧和平面的交点
            {
                double[] arcFrac = new double[2];  // 交点的参数数组
                XPoint3d[] pts = new XPoint3d[2];  // 交点数组
                int count;  // 交点个数

                // 求交，返回交点个数和交点坐标
                bool isSuccess = XEllipse3d.Intersect(arc, plane, arcFrac, pts, out count);  // 计算交点
                for (int i = 0; i < count; i++)  // 遍历交点
                {
                    UseSomeBasicMethods.AddToScene_Xpoint(pts[i], i);  // 将交点添加到场景中
                }
            }
        }


        /// <summary>
        /// XEllipse求交
        /// IntersectXYXEllipse3dBounded
        /// </summary>
        public static void Intersect2Arc()
        {
            XEllipse3d arc1 = CreateCurveSetMethods.CreateXEllipse3d_FromCenterStartEndPts();
            XEllipse3d arc2 = CreateCurveSetMethods.CreateXEllipse3d_FromStartPtTangentNormalRadiusSweep().Value();
            UseSomeBasicMethods.AddToScene_XEllipse3d(arc1);
            UseSomeBasicMethods.AddToScene_XEllipse3d(arc2);

            //计算两个圆弧在XY面上的交点，认为圆弧有界IntersectXYXEllipse3dBounded
            {
                //出参：在两个圆弧上的交点和角度
                List<XPoint3d> carPts = new List<XPoint3d>(); // 交点坐标
                List<XPoint3d> elli0Coff = new List<XPoint3d>(); // 交点的转角 x=cos(a), y=sin(a), 转角相对圆的起始半径
                List<double> elli0Angle = new List<double>();    // 交点的转角.
                List<XPoint3d> elli1Coff = new List<XPoint3d>();
                List<double> elli1Angle = new List<double>();

                int num = arc1.IntersectXYXEllipse3dBounded(out carPts, out elli0Coff, out elli0Angle, out elli1Coff, out elli1Angle, arc2);
                for (int i = 0; i < num; i++)
                {
                    UseSomeBasicMethods.AddToScene_Xpoint(carPts[i], i);
                }
            }

        }
        #endregion

        #region B样条曲线求交
        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/样条曲线交点。
        /// 功能：计算并显示两个B样条曲线的交点。
        /// 关键类及说明：
        ///     ATBsplineCurve: 表示B样条曲线。
        ///     CurveSet: BasicCurve的集合。此类可以是一组没有关系的BasicCurve，也可以组合多个BasicCurve，表达封闭多边形、开放线条，进而可以进行求交、分割、求面积等操作。
        ///               在玄镜平台几何话题中，大多数场景下，线集与“轮廓”经常互用；线集与“曲线”（广义的，封闭、非封闭；平面、非平面）经常互用。
        ///     ATObject: 表示场景中的几何对象。
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateATBsplineCurves_FromControlPts: 从控制点创建B样条曲线。
        ///     CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts: 从经过点创建B样条曲线。
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中。
        ///     GeometryToATObject.ToObject: 将几何数据转换为场景对象。
        ///     Intersect2Object: 计算两个几何对象的交点。
        /// </summary>
        public static void Intersect2BsplineObject()
        {
            // 创建两个B样条曲线，并显示到界面上
            ATBsplineCurve spline = CreateCurveSetMethods.CreateATBsplineCurves_FromControlPts(false);  // 从控制点创建第一个B样条曲线
            CurveSet crv1 = CurveSet.Create(CurveSet.BoundaryType.Open);  // 创建曲线集，边界类型为Open（不能为None）
            crv1.Add(BasicCurve.CreateBsplineCurve(spline));  // 将第一个B样条曲线添加到曲线集中

            ATBsplineCurve spline2 = CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts(false);  // 从经过点创建第二个B样条曲线
            CurveSet crv2 = CurveSet.Create(CurveSet.BoundaryType.Open);  // 创建另一个曲线集，边界类型为Open
            crv2.Add(BasicCurve.CreateBsplineCurve(spline2));  // 将第二个B样条曲线添加到曲线集中

            UseSomeBasicMethods.AddToScene_CurveSet(crv1, 1);  // 将第一个曲线集添加到场景中，颜色标记为1
            UseSomeBasicMethods.AddToScene_CurveSet(crv2, 2);  // 将第二个曲线集添加到场景中，颜色标记为2

            // 将曲线集转换为场景对象，并计算交点
            {
                ATObject curveSet1Obj = GeometryToATObject.ToObject(scene.GetATScene(), crv1, null);  // 将第一个曲线集转换为场景对象
                ATObject curveSet2Obj = GeometryToATObject.ToObject(scene.GetATScene(), crv2, null);  // 将第二个曲线集转换为场景对象

                Intersect2Object(curveSet1Obj, curveSet2Obj);  // 计算并处理两个场景对象的交点
            }
        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/对象交点。
        /// 功能：计算并显示两个几何对象的交点。
        /// 关键类及说明：
        ///     ATObject: 玄镜图形平台基于面向对象思想抽象的平台对象。基于这个类，平台进行统一的显示、存储、查询、修改等操作。
        ///               几何类（CurveSet/BasicCurve/XSegment3d/XEllipse3d等）、实体类（SolidCoreEntity）、文本块类（TextBlock）、标注类（ATDimension）、表格类（TextTable）、网格类（PolyfaceMeshObject）等都可以与ATObject双向转换。
        ///     XPoint3d: 表示三维空间中的点。
        ///     XMatrix3d: 表示三维空间中的矩阵，用于几何变换。
        /// 关键方法：
        ///     SSDPNET.ATCalFuncs.IntersectAllBetweenObjects: 计算两个几何对象之间的所有交点。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将交点显示在场景中。
        /// </summary>
        /// <param name="obj1">第一个几何对象</param>
        /// <param name="obj2">第二个几何对象</param>
        public static void Intersect2Object(ATObject obj1, ATObject obj2)
        {
            int pntSize = 3; // 决定了交点集合的大小，pnt1.Count和pnt2.Count = pntSize
            List<XPoint3d> pnt1, pnt2; // 存储交点的列表
            XMatrix3d matrix = XMatrix3d.Identity; // 单位矩阵，用于几何变换
                                                   // 返回交点个数
            int count = SSDPNET.ATCalFuncs.IntersectAllBetweenObjects(out pnt1, out pnt2, pntSize, obj1, obj2, matrix, 1);
            // 将交点显示在场景中
            for (int i = 0; i < count; i++)
            {
                UseSomeBasicMethods.AddToScene_Xpoint(pnt1[i], 1); // 将第一个对象的交点显示在场景中，颜色标记为1
            }
            for (int i = 0; i < count; i++)
            {
                UseSomeBasicMethods.AddToScene_Xpoint(pnt2[i], 2); // 将第二个对象的交点显示在场景中，颜色标记为2
            }
        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/曲线与平面求交。
        /// 功能：计算并显示B样条曲线与平面的交点。
        /// 关键类及说明：
        ///     ATBsplineCurve: 表示B样条曲线。
        ///     XPlane3d: 表示三维空间中的平面，通过一个点和一个法向量定义。
        ///     XPoint3d: 表示三维空间中的点。
        ///     XVector3d: 表示三维空间中的向量。
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts: 通过指定点生成B样条曲线。
        ///     UseSomeBasicMethods.AddToScene_ATBsplineCurve: 将B样条曲线添加到场景中。
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中，并指定颜色。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     ATBsplineCurve.AddPlaneIntersections: 计算B样条曲线与平面的交点。
        /// </summary>
        public static void IntersectBsplinePlane()
        {
            // 1. 构造B样条曲线
            ATBsplineCurve bsplineCurve = CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts(false);
            UseSomeBasicMethods.AddToScene_ATBsplineCurve(bsplineCurve);

            // 2. 构造平面--无限大
            XPoint3d origin = new XPoint3d(50, 0, 0); // 平面上的一点
            XVector3d normal = XVector3d.UnitX; // 平面的法向量
            XPlane3d plane = new XPlane3d(origin, normal); // 通过平面上的一点和法向量构造平面
            {
                // 绘制平面--示意
                CurveSet curve = CreatePlaneYOZ(origin); // 创建YOZ平面的曲线集
                UseSomeBasicMethods.AddToScene_CurveSet(curve, 3); // 将曲线集添加到场景中，颜色标记为3
            }

            {
                // 出参：点集
                List<XPoint3d> listPts = new List<XPoint3d>();
                // 出参：B样条曲线上的交点参数
                List<double> listFracs = new List<double>();
                bsplineCurve.AddPlaneIntersections(listPts, listFracs, ref plane); // 计算B样条曲线与平面的交点
                for (int i = 0; i < listPts.Count; i++)
                {
                    UseSomeBasicMethods.AddToScene_Xpoint(listPts[i], i + 4); // 将交点添加到场景中，颜色标记为i + 4
                }
            }
        }

        #endregion

        #region 不同对象求交
        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/曲线与线段求交。
        /// 功能：计算并显示圆弧与线段的交点。
        /// 关键类及说明：
        ///     XEllipse3d: 表示三维空间中的椭圆或圆弧。
        ///     XSegment3d: 表示三维空间中的线段。
        ///     XPoint3d: 表示三维空间中的点。
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateXEllipse3d_FromCenterRadiusNormal: 通过中心点、半径和法向量生成圆弧。
        ///     CreateCurveSetMethods.CreateXSegmentFromStartEnd: 通过起点和终点生成线段。
        ///     UseSomeBasicMethods.AddToScene_XEllipse3d: 将圆弧添加到场景中。
        ///     UseSomeBasicMethods.AddToScene_XSegment: 将线段添加到场景中。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     XEllipse3d.IntersectSweptXSegment3d: 计算圆弧和线段的交点。
        /// </summary>
        public static void IntersectArcSeg()
        {
            XEllipse3d arc = CreateCurveSetMethods.CreateXEllipse3d_FromCenterRadiusNormal(); // 通过中心点、半径和法向量生成圆弧
            UseSomeBasicMethods.AddToScene_XEllipse3d(arc); // 将圆弧添加到场景中

            XSegment3d seg2 = CreateCurveSetMethods.CreateXSegmentFromStartEnd(); // 通过起点和终点生成线段
            UseSomeBasicMethods.AddToScene_XSegment(seg2); // 将线段添加到场景中

            // 计算线段与圆弧相交的交点，椭圆弧和线段都视为无界的
            {
                List<XPoint3d> pointArray = new List<XPoint3d>(); // 出参1：交点集合
                List<XPoint3d> ellipseParams = new List<XPoint3d>(); // 出参2：圆弧上的参数
                List<double> pLineParams = new List<double>(); // 出参3：线段上的参数

                int num = arc.IntersectSweptXSegment3d(out pointArray, out ellipseParams, out pLineParams, seg2); // 计算圆弧和线段的交点
                for (int i = 0; i < pointArray.Count; i++)
                {
                    UseSomeBasicMethods.AddToScene_Xpoint(pointArray[i], i); // 将交点添加到场景中，颜色标记为i
                }
            }
        }


        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/曲线与线段求交。
        /// 功能：计算并显示B样条曲线与线段的交点。
        /// 关键类及说明：
        ///     ATBsplineCurve: 表示B样条曲线。
        ///     XSegment3d: 表示三维空间中的线段。
        ///     XPoint3d: 表示三维空间中的点。
        ///     XMatrix4d: 表示四维空间中的矩阵，用于几何变换。
        /// 关键方法：
        ///     CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts: 通过指定点生成B样条曲线。
        ///     CreateCurveSetMethods.CreateXSegmentFromStartEnd: 通过起点和终点生成线段。
        ///     UseSomeBasicMethods.AddToScene_ATBsplineCurve: 将B样条曲线添加到场景中。
        ///     UseSomeBasicMethods.AddToScene_XSegment: 将线段添加到场景中。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     ATBsplineCurve.AddLineIntersectionsXY: 计算B样条曲线与线段在XY方向上的交点。
        /// </summary>
        public static void IntersectBsplineXseg()
        {
            ATBsplineCurve bsplineCurve = CreateCurveSetMethods.CreateATBsplineCurves_FromThroughPts(false); // 构造B样条曲线
            UseSomeBasicMethods.AddToScene_ATBsplineCurve(bsplineCurve); // 将B样条曲线添加到场景中

            XSegment3d seg2 = CreateCurveSetMethods.CreateXSegmentFromStartEnd(); // 构造线段
            UseSomeBasicMethods.AddToScene_XSegment(seg2); // 将线段添加到场景中

            {
                List<XPoint3d> listPtA = new List<XPoint3d>(); // 出参 B样条曲线上的点
                List<double> listFracA = new List<double>(); // 出参 B样条曲线上的参数

                List<XPoint3d> listPtB = new List<XPoint3d>(); // 出参 线段上的点
                List<double> listFracB = new List<double>(); // 出参 线段上的参数

                bool isExtendSeg = true; // 是否延长线段
                XMatrix4d matrix = XMatrix4d.Identity; // 单位矩阵，用于几何变换

                bsplineCurve.AddLineIntersectionsXY(listPtA, listFracA, listPtB, listFracB, ref seg2, isExtendSeg, ref matrix); // 在XY方向上计算B样条曲线与直线的交点

                for (int i = 0; i < listPtA.Count; i++)
                {
                    UseSomeBasicMethods.AddToScene_Xpoint(listPtA[i], i + 4); // 将交点显示在视口中，颜色标记为i + 4
                }
            }
        }

        #endregion

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/绘制/平面显示。
        /// 功能：将平面显示在视口中的辅助函数--平面的示意，平面是无界的。
        /// 关键类及说明：
        ///     XPoint3d: 表示三维空间中的点。
        ///     CurveSet: 表示一组曲线的集合，可以用于绘制平面。
        /// 关键方法：
        ///     CurveSet.CreateLinear: 通过一组点创建线性曲线集。
        /// </summary>
        /// <param name="origin">平面上的一点，用于确定平面的位置。</param>
        /// <returns>返回表示平面的曲线集。</returns>
        public static CurveSet CreatePlaneYOZ(XPoint3d origin)
        {
            double enoughLong = 500; // 平面的显示长度
            XPoint3d pt1 = origin; // 平面上的一个点
            pt1.Z = origin.Z - enoughLong; // 计算平面的一点，Z坐标减去长度
            pt1.Y = origin.Y - enoughLong; // 计算平面的一点，Y坐标减去长度

            XPoint3d pt2 = pt1; // 复制点pt1
            pt2.Y = pt1.Y + enoughLong * 2; // 计算平面上的另一个点，Y坐标加上两倍长度

            XPoint3d pt3 = pt2; // 复制点pt2
            pt3.Z = pt2.Z + enoughLong * 2; // 计算平面上的另一个点，Z坐标加上两倍长度

            XPoint3d pt4 = pt3; // 复制点pt3
            pt4.Y = pt3.Y - enoughLong * 2; // 计算平面上的另一个点，Y坐标减去两倍长度

            List<XPoint3d> listPts = new List<XPoint3d>() { pt1, pt2, pt3, pt4 }; // 创建包含四个点的列表
            CurveSet curve = CurveSet.CreateLinear(listPts, CurveSet.BoundaryType.Outer, false); // 创建表示平面的曲线集
            return curve; // 返回曲线集
        }


        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/线集合与平面求交。
        /// 功能：展示如何计算并显示线集合与平面的交点。
        /// 关键类及说明：
        ///     ButtonsView: 提供用于展示和操作按钮的视图。
        ///     XPoint3d: 表示三维空间中的点。
        ///     XVector3d: 表示三维空间中的向量。
        ///     XPlane3d: 表示三维空间中的平面，通过一个点和一个法向量定义。
        ///     CurveSet: 表示一组曲线的集合。
        /// 关键方法：
        ///     UseSomeBasicMethods.ClearScene: 清空视口中的所有对象。
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中，并指定颜色。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     IntersectClosedCurveSetPlane: 计算并显示闭合轮廓与平面的交点。
        ///     IntersectCurveSetPlane: 计算并显示线集合与平面的交点。
        /// </summary>
        public static void IntersectCurveSetExample()
        {
            UseSomeBasicMethods.ClearScene(); // 清空视口

            ButtonsView v = new ButtonsView(); // 创建按钮视图

            v.AddButton("计算闭合轮廓与平面的交点", (object sender, RoutedEventArgs e) =>
            {
                IntersectClosedCurveSetPlane(); // 计算闭合轮廓与平面的交点
            });

            v.AddButton("计算轮廓与平面的交点", (object sender, RoutedEventArgs e) =>
            {
                IntersectCurveSetPlane(); // 计算轮廓与平面的交点
            });
            v.Show(); // 显示按钮视图
        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/闭合轮廓与平面求交。
        /// 功能：计算并显示闭合轮廓与平面的交点。
        /// 关键类及说明：
        ///     XPoint3d: 表示三维空间中的点。
        ///     XVector3d: 表示三维空间中的向量。
        ///     XEllipse3d: 表示三维空间中的椭圆。
        ///     XPlane3d: 表示三维空间中的平面，通过一个点和一个法向量定义。
        ///     SSDPNET.CurveDescInfoPair: 表示曲线描述信息对，包含交点信息。
        /// 关键方法：
        ///     CreatePlaneYOZ: 创建并返回表示平面的曲线集。
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中，并指定颜色。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     XEllipse3d.FromCenterRadiusNormal: 通过中心、半径和法向量创建椭圆。
        ///     SSDPNET.CurveDescInfoPair: 用于存储曲线交点的描述信息。
        ///     CurveSet.CreateDisk: 创建表示圆盘的曲线集。
        ///     XPlane3d: 创建表示平面的对象。
        ///     AppendClosedCurvePlaneIntersections: 计算闭合轮廓与平面的交点。
        /// </summary>
        public static void IntersectClosedCurveSetPlane()
        {
            XPoint3d origin = new XPoint3d(0, -15, 0); // 平面上的一点
            XVector3d arcNormal = XVector3d.UnitZ; // 椭圆的法向量
            XEllipse3d arc = XEllipse3d.FromCenterRadiusNormal(origin, 50, arcNormal); // 创建椭圆
            CurveSet crv1 = CurveSet.CreateDisk(arc, CurveSet.BoundaryType.Outer); // 创建表示圆盘的曲线集
            UseSomeBasicMethods.AddToScene_CurveSet(crv1); // 将曲线集添加到场景中

            XVector3d normal = XVector3d.UnitX; // 平面的法向量
            XPlane3d plane = new XPlane3d(origin, normal); // 创建平面
            {
                CurveSet curve = CreatePlaneYOZ(origin); // 创建表示平面的曲线集
                UseSomeBasicMethods.AddToScene_CurveSet(curve, 3); // 将曲线集添加到场景中，颜色标记为3
            }

            {
                List<SSDPNET.CurveDescInfoPair> intersections = new List<SSDPNET.CurveDescInfoPair>(); // 交点集合
                double tolerance = 1e-7; // 计算容差
                crv1.AppendClosedCurvePlaneIntersections(plane, out intersections, tolerance); // 计算闭合轮廓与平面的交点
                if (intersections.Count() != 0) // 如果有交点
                {
                    CurveDescInfo A = intersections[0].detailA; // 取第一个交点信息
                    CurveDescInfo B = intersections[0].detailB; // 取第一个交点信息
                    UseSomeBasicMethods.AddToScene_Xpoint(A.Point, 1); // 将交点A添加到场景中，颜色标记为1
                    UseSomeBasicMethods.AddToScene_Xpoint(B.Point, 2); // 将交点B添加到场景中，颜色标记为2
                }
            }
        }

        /// <summary>
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/几何/计算/轮廓与平面求交。
        /// 功能：计算并显示轮廓与平面的交点。
        /// 关键类及说明：
        ///     XPoint3d: 表示三维空间中的点。
        ///     XVector3d: 表示三维空间中的向量。
        ///     XPlane3d: 表示三维空间中的平面，通过一个点和一个法向量定义。
        ///     CurveSet: 表示一组曲线的集合。
        ///     SSDPNET.CurveDescInfoPair: 表示曲线描述信息对，包含交点信息。
        /// 关键方法：
        ///     CreatePlaneYOZ: 创建并返回表示平面的曲线集。
        ///     UseSomeBasicMethods.AddToScene_CurveSet: 将曲线集添加到场景中，并指定颜色。
        ///     UseSomeBasicMethods.AddToScene_Xpoint: 将点添加到场景中，并指定颜色。
        ///     XSegment3d: 表示三维空间中的线段。
        ///     SSDPNET.CurveDescInfoPair: 用于存储曲线交点的描述信息。
        ///     AppendCurvePlaneIntersections: 计算轮廓与平面的交点。
        /// </summary>
        public static void IntersectCurveSetPlane()
        {
            XSegment3d seg = CreateCurveSetMethods.CreateHorizonXseg(); // 创建水平线段
            CurveSet crv1 = CurveSet.Create(CurveSet.BoundaryType.Open); // 创建表示线串的曲线集
            crv1.Add(BasicCurve.CreateLine(seg)); // 将线段添加到曲线集中
            UseSomeBasicMethods.AddToScene_CurveSet(crv1); // 将曲线集添加到场景中

            XPoint3d origin = new XPoint3d(-50, -15, 0); // 平面上的一点
            XVector3d normal = XVector3d.UnitX; // 平面的法向量
            XPlane3d plane = new XPlane3d(origin, normal); // 创建平面
            {
                CurveSet curve = CreatePlaneYOZ(origin); // 创建表示平面的曲线集
                UseSomeBasicMethods.AddToScene_CurveSet(curve, 3); // 将曲线集添加到场景中，颜色标记为3
            }

            {
                List<SSDPNET.CurveDescInfoPair> intersections = new List<SSDPNET.CurveDescInfoPair>(); // 交点集合
                double tolerance = 1e-7; // 计算容差

                crv1.AppendCurvePlaneIntersections(plane, out intersections, tolerance); // 计算轮廓与平面的交点
                if (intersections.Count() != 0) // 如果有交点
                {
                    CurveDescInfo A = intersections[0].detailA; // 取第一个交点信息
                    CurveDescInfo B = intersections[0].detailB; // 取第一个交点信息
                    UseSomeBasicMethods.AddToScene_Xpoint(A.Point, 1); // 将交点A添加到场景中，颜色标记为1
                    UseSomeBasicMethods.AddToScene_Xpoint(B.Point, 2); // 将交点B添加到场景中，颜色标记为2
                }
            }
        }

    }

}
